package com.itheima.aspect;

import com.itheima.transaction.MyTransaction;
import com.itheima.transaction.TransactionManager;
import com.itheima.utils.DataSourceUtil;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;

@Component

@Aspect
public class TransactionAspect {
    @Autowired
    private TransactionManager transactionManager;

    //关心是 service包及其子包下的所有类的所有方法
    @Around("execution( * com.itheima.service..*.*(..))")
    public Object around(ProceedingJoinPoint pjp){
        Object result=null;


        Signature signature = pjp.getSignature();
        String methodName = signature.getName();

        //正在被加强对象类
        Class<?> aClass = pjp.getTarget().getClass();

        Method[] declaredMethods = aClass.getDeclaredMethods();
        //遍历方法 找到那个方法

        Method targetMethod=null;
        for (Method declaredMethod : declaredMethods) {
            if (declaredMethod.getName().equals(methodName)){
                targetMethod=declaredMethod;
                break;
            }
        }

        if (!targetMethod.isAnnotationPresent(MyTransaction.class)){
            System.out.println("没有添加控制");
            try {
                result=pjp.proceed();
            } catch (Throwable e) {
                throw new RuntimeException(e);
            }
            return result;
        }



        //百分百需要事务
        MyTransaction annotation = targetMethod.getAnnotation(MyTransaction.class);

        boolean readOnly=false;

        if (annotation.readOnly()||annotation.value()){
            readOnly=true;
        }



        try {
            System.out.println("添加了事务控制");
            transactionManager.start(readOnly);
            //业务逻辑start~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

            result=pjp.proceed();

            //业务逻辑end~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
            transactionManager.commit();
        }catch (Throwable e){
            transactionManager.rollback();
            throw new RuntimeException(e);
        }finally {
            DataSourceUtil.close();
        }

        return result;
    }



}
